package com.ttg.web.service.Impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ttg.common.constant.BasicConstant;
import com.ttg.common.dto.TagProducer;
import com.ttg.common.entities.BasePage;
import com.ttg.common.entities.BaseResult;
import com.ttg.common.entities.RattingTask;
import com.ttg.common.enums.*;
import com.ttg.common.enums.BankPublicTradeEnum;
import com.ttg.common.enums.ErrorCodeEnums;
import com.ttg.common.enums.RulesTypeEnum;
import com.ttg.common.exception.BaseException;
import com.ttg.common.utils.DateTimeUtil;
import com.ttg.model.dto.*;
import com.ttg.model.pojo.*;
import com.ttg.model.vo.*;
import com.ttg.web.dao.*;
import com.ttg.web.service.MctInfoService;
import com.ttg.web.service.VipGrowthIntegrationManagementService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.util.CollectionUtils;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
@Slf4j
public class MctInfoServiceImpl implements MctInfoService {

    @Autowired
    private VipGrowDetailDao vipGrowDetailDao;

    @Autowired
    private BankPublicPrimitiveDao bankPublicPrimitiveDao;

    @Autowired
    private VipGradeConfigDao vipGradeConfigDao;

    @Autowired
    private RulesListDao rulesListDao;

    @Autowired
    private VipRattingConfigDao vipGradeRattingDao;

    @Autowired
    private VipGrowthIntegrationManagementService vipGrowthIntegrationManagementService;

    @Autowired
    private BankPublicTradePrimitiveDao bankPublicTradePrimitiveDao;

    @Autowired
    private VipBindTagDao vipBindTagDao;

    @Autowired
    private MctNextGradeTempDao mctNextGradeTempDao;

    @Autowired
    private MctLastGradeBakDao mctLastGradeBakDao;

    @Autowired
    private PlatformTransactionManager transactionManager;

    @Value("${autotask.pageSize}")
    private Integer pageSize;

    @Override
    public BasePage<VipIntegralDetailDto> getMctIntegralDetail(MctDetailDto mctDetailDto) {
        if (Objects.isNull(mctDetailDto)||StringUtils.isBlank(mctDetailDto.getMctNo())) {
            throw new BaseException(ErrorCodeEnums.PARAM_IS_NULL);
        }
        BasePage<Object> parse = mctDetailDto.parse();
        BasePage<VipGrowDetail> page = new BasePage<>(parse.getCurrent(), parse.getSize(), parse.getTotal(), parse.isSearchCount());
//        BasePage<VipGrowDetail> pageInfo = vipIntegralDetailDao.getMctIntegralDetail(page, mctDetailDto);
        BasePage<VipGrowDetail> pageInfo = vipGrowDetailDao.getMctIntegralDetail(page, mctDetailDto);
        BasePage<VipIntegralDetailDto> basePage = new BasePage<>();
        basePage.setPagesRes(pageInfo.getPagesRes());
        List<VipIntegralDetailDto> dtos = new ArrayList<>();
        List<VipGrowDetail> list = pageInfo.getList();
        if (!CollectionUtils.isEmpty(list)) {
            for (VipGrowDetail vipGrowDetail : list) {
                VipIntegralDetailDto vipIntegralDetailDto = new VipIntegralDetailDto();
                BeanUtils.copyProperties(vipGrowDetail, vipIntegralDetailDto);
                vipIntegralDetailDto.setIntegral(vipGrowDetail.getIntegral() + "");
                dtos.add(vipIntegralDetailDto);
            }
        }
        basePage.setList(dtos);
        return basePage;


    }

    @Override
    public BasePage<MctDetailVo>  getMctGrowDetail(MctDetailDto mctDetailDto) {
        if (Objects.isNull(mctDetailDto)|| StringUtils.isBlank(mctDetailDto.getMctNo())) {
            throw new BaseException(ErrorCodeEnums.PARAM_IS_NULL);
        }
        BasePage<Object> parse = mctDetailDto.parse();
        BasePage<VipGrowDetail> page = new BasePage<>(parse.getCurrent(), parse.getSize(), parse.getTotal(), parse.isSearchCount());
        BasePage<VipGrowDetail> pageInfo = vipGrowDetailDao.getMctGrowDetail(page, mctDetailDto);
        BasePage<MctDetailVo> basePage = new BasePage<>();
        basePage.setPagesRes(pageInfo.getPagesRes());
        List<MctDetailVo> vipGrowDetailDtos = new ArrayList<>();
        List<VipGrowDetail> list = pageInfo.getList();
        if (!CollectionUtils.isEmpty(list)) {
            for (VipGrowDetail vipGrowDetail : list) {
                MctDetailVo mctDetailVo = new MctDetailVo();
                BeanUtils.copyProperties(vipGrowDetail, mctDetailVo);
//                mctDetailVo.setGrowNum(vipGrowDetail.getGrowNum() + "");
                vipGrowDetailDtos.add(mctDetailVo);
            }
        }
        basePage.setList(vipGrowDetailDtos);
        return basePage;
    }

    @Override
    public BasePage<MctInfoListGetVo> getList(MctInfoListGetDto mctInfoListGetDto) {
        if (Objects.isNull(mctInfoListGetDto)) {
            throw new BaseException(ErrorCodeEnums.PARAM_IS_NULL);
        }
        BasePage<Object> parse = mctInfoListGetDto.parse();

        BasePage<VipInfoGetListVo> page = new BasePage<>(parse.getCurrent(), parse.getSize(), parse.getTotal(), parse.isSearchCount());

        BasePage<MctInfoListGetVo> list = bankPublicPrimitiveDao.getList(page, mctInfoListGetDto);
        List<VipGradeConfig> vipGradeConfigs = vipGradeConfigDao.list(new LambdaQueryWrapper<VipGradeConfig>()
                .eq(Objects.nonNull(mctInfoListGetDto.getMctGrade()), VipGradeConfig::getVipGrade, mctInfoListGetDto.getMctGrade())
                .eq(VipGradeConfig::getGradeType,1));
        Map<Double, String> map = vipGradeConfigs.stream().collect(Collectors.toMap(VipGradeConfig::getVipGrade, VipGradeConfig::getVipName));
        List<String> mctNos = list.getList().stream().map(MctInfoListGetVo::getMctNo).collect(Collectors.toList());
        Map<String,Map<String,Integer>> mapMap=null;
        if (!mctNos.isEmpty()){
            mapMap= vipBindTagDao.numByMctNos(mctNos);
        }
        for (MctInfoListGetVo mctInfoListGetVo : list.getList()) {
            if (ObjectUtil.isNotNull(mctInfoListGetVo.getMctGrade()) && StringUtils.isNotBlank(mctInfoListGetVo.getMctGrade())){
                mctInfoListGetVo.setVipGradeName(map.get(Double.valueOf(mctInfoListGetVo.getMctGrade())));
            }
            Map<String, Integer> stringIntegerMap = mapMap.get(mctInfoListGetVo.getMctNo());
            if (ObjectUtil.isNotNull(stringIntegerMap)){
                    mctInfoListGetVo.setMctBindTagNum(String.valueOf(stringIntegerMap.get("num")));
                }else {
                    mctInfoListGetVo.setMctBindTagNum(String.valueOf(BasicConstant.INT_0));
                }
        }
        return list;
    }

    @Override
    public MctInfoEditVo editMct(MctInfoEditDto mctInfoEditDto) {
        if (Objects.isNull(mctInfoEditDto)||StringUtils.isEmpty(mctInfoEditDto.getMctId())) {
            throw new BaseException(ErrorCodeEnums.PARAM_IS_NULL);
        }
        BankPublicPrimitive bankPublicPrimitive = new BankPublicPrimitive();
        bankPublicPrimitive.setId(Long.valueOf(mctInfoEditDto.getMctId()));
        bankPublicPrimitive.setMctGrade(mctInfoEditDto.getMctGrade());
        if (StringUtils.isNotEmpty(mctInfoEditDto.getMctEndTime())){
            bankPublicPrimitive.setMctGradeDate(DateTimeUtil.parseDateFormatStr(mctInfoEditDto.getMctEndTime()));
        }
        MctInfoEditVo vo = new MctInfoEditVo();
        vo.setStatus(ErrorCodeEnums.SYSTEM_ERROR.getErrcode());
       if (bankPublicPrimitiveDao.updateById(bankPublicPrimitive)) {
            vo.setStatus(ErrorCodeEnums.SUCCESS.getErrcode());
       }

        return vo;
    }

    @Override
    @RattingTask(taskEnum = TaskEnum.EDIT_MCT_RATING)
    public boolean editMctRating() {
        LocalDate now = LocalDate.now();
        Integer date = Integer.valueOf(DateTimeUtil.formatYYYYMMDD(now));
        //备份是否有效（备份有效期与等级更新时间一致，为一个月）
        Integer checkDate = Integer.valueOf(DateTimeUtil.formatYYYYMMDD(now.minusMonths(BasicConstant.INT_1)));
        MctLastGradeBak bakRuslt = mctLastGradeBakDao.checkBakResultByDate(checkDate);
        //本次评级未备份
        if (Objects.isNull(bakRuslt)){
            //清除之前的备份
            mctLastGradeBakDao.truncateOldRecords();
            //添加事务确保备份一次备份完全
            DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
            //隔离级别
            definition.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
            //传播行为
            definition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
            TransactionStatus status = transactionManager.getTransaction(definition);
            try {
                //重新备份
                mctLastGradeBakDao.mctBak(date);
                transactionManager.commit(status);
            }catch (Exception e){
                transactionManager.rollback(status);
                log.error("商户会员等级备份失败，日期"+date+"==================>{}",e.getMessage());
                throw  e;
            }

        }

        //清除上次评级结果
        mctNextGradeTempDao.truncateOldRecords();
        //评级
        mctNextGradeTempDao.mctRating(date);
        BankPublicPrimitive  mct = bankPublicPrimitiveDao.getLastMctId();
        Long idStart = BasicConstant.LONG_1;
        Long lastId = mct.getId();
        while (true){
            if (idStart > lastId){
                break;
            }
            Long idEnd = idStart + 10000L;
            bankPublicPrimitiveDao.rattingGradeByBatch(idStart,idEnd);
            idStart = idEnd;
        }
        return true;
    }

//    @Override
//    public boolean editMctRating() {
//        List<VipGradeConfig> list = vipGradeConfigDao.getVipGradeByType(GradeTypeEnum.TYPE_PUBLIC.getValue());
//        if (CollectionUtils.isEmpty(list)) {
//            throw new BaseException(ErrorCodeEnums.VIP_GRADE_IS_NULL);
//        }
//        for (VipGradeConfig vipGradeConfig : list) {
//            bankPublicPrimitiveDao.editMctRatingByVipGradeConfig(vipGradeConfig);
//        }
//        return true;
//    }

    @Override
    public MctInfoDeleteVo deleteMct(MctInfoDeleteDto mctInfoDeleteDto) {
        return null;
    }



    @Override
    @RattingTask(taskEnum = TaskEnum.MCT_RATING_REGISTER_YEAR)
    public BaseResult startMctRatingRegisterYear() {
        return mctSumGrowAndIntegral(RulesTypeEnum.TYPE_1);
    }

    @Override
    @RattingTask(taskEnum = TaskEnum.MCT_RATING_PRACTISE_YEAR)
    public BaseResult startMctRatingPractiseYear() {
        return mctSumGrowAndIntegral(RulesTypeEnum.TYPE_2);
    }

    @Override
    @RattingTask(taskEnum = TaskEnum.MCT_RATING_PERIODICALLY_DEPOSIT)
    public BaseResult startMctRatingPeriodicallyDeposit() {
        return mctSumGrowAndIntegral(RulesTypeEnum.TYPE_3);
    }


    @Override
    @RattingTask(taskEnum = TaskEnum.MCT_RATING_CURRENT_DEPOSIT)
    public BaseResult startMctRatingCurrentDeposit() {
        return mctSumGrowAndIntegral(RulesTypeEnum.TYPE_4);
    }

    @Override
    @RattingTask(taskEnum = TaskEnum.MCT_RATING_FINANCING)
    public BaseResult startMctRatingFinancing() {
        return mctSumGrowAndIntegral(RulesTypeEnum.TYPE_5);
    }

    @Override
    @RattingTask(taskEnum = TaskEnum.MCT_RATING_LOAN_AMOUNT)
    public BaseResult startMctRatingLoanAmount() {
        return mctSumGrowAndIntegral(RulesTypeEnum.TYPE_6);
    }

    @Override
    @RattingTask(taskEnum = TaskEnum.MCT_RATING_TRANSACTION_MOUTH_NUMBER)
    public BaseResult startMctRatingTransactionMonthNumber() {
        return mctSumGrowAndIntegral(RulesTypeEnum.TYPE_7);
    }

    @Override
    @RattingTask(taskEnum = TaskEnum.MCT_RATING_TRANSACTION_AMOUNT)
    public BaseResult startMctRatingTransactionAmount() {
        return mctSumGrowAndIntegral(RulesTypeEnum.TYPE_8);
    }

    @Override
    @RattingTask(taskEnum = TaskEnum.MCT_RATING_QUARTER_TRANSACTION_AMOUNT)
    public BaseResult startMctRatingQuarterTransactionAmount() {
        return mctSumGrowAndIntegral(RulesTypeEnum.TYPE_9);
    }

    @Override
    @RattingTask(taskEnum = TaskEnum.MCT_RATING_TRANSACTION_NUMBER)
    public BaseResult startMctRatingTransactionNumber() {
        return mctSumGrowAndIntegral(RulesTypeEnum.TYPE_10);
    }

    @Override
    @RattingTask(taskEnum = TaskEnum.MCT_RATING_QUARTER_TRANSACTION_NUMBER)
    public BaseResult startMctRatingQuarterTransactionNumber() {
        return mctSumGrowAndIntegral(RulesTypeEnum.TYPE_11);
    }

    @Override
    @RattingTask(taskEnum = TaskEnum.NEW_MCT_RATING)
    public boolean newMctRating() {
        return bankPublicPrimitiveDao.newMctRating();
    }


    public BaseResult mctSumGrowAndIntegral(RulesTypeEnum rulesTypeEnum) {
        if (Objects.isNull(rulesTypeEnum) || Objects.isNull(rulesTypeEnum.getTableName()) || Objects.isNull(rulesTypeEnum.getColumnName())){
            return BaseResult.defaultFail();
        }

        RulesList byId = rulesListDao.getById(rulesTypeEnum.getCode());
        if (Objects.isNull(byId)) {
            return BaseResult.defaultFail();
        }
        if (!RulesStatusEnum.OPEN.getValue().equals(byId.getStatus())){
            //已停用
            return BaseResult.success(true);
        }
        LocalDateTime nowTime = LocalDateTime.now();
        Integer nowDate = Integer.valueOf(DateTimeUtil.formatYYYYMMDD(LocalDate.now()));
        //当日多次执行时仅记录最后一次执行的积分
        vipGrowDetailDao.removeByTaskIdAndDate(Long.valueOf(rulesTypeEnum.getCode()),nowDate);

        List<VipRatingConfig> rattingRulesListByRulesId = vipGradeRattingDao.getRattingRulesListByRulesId(String.valueOf(byId.getId()));
        if (Objects.isNull(rattingRulesListByRulesId) || CollectionUtils.isEmpty(rattingRulesListByRulesId)){
           throw new BaseException(ErrorCodeEnums.TASK_GROW_RULE_CONFIG_ERR.getErrcode(),ErrorCodeEnums.TASK_GROW_RULE_CONFIG_ERR.getMsg());
        }
        List<VipRatingConfig> sortedList = rattingRulesListByRulesId.stream().sorted(Comparator.comparingLong(VipRatingConfig::getRatingStart)).collect(Collectors.toList());
        //取出最高一档配置
        VipRatingConfig maxConfig = sortedList.get(sortedList.size()-1);
        //去除集合内最高档配置
        sortedList.remove(sortedList.size()-1);

        MctGrowAndIntegralSumDto sumDto = new MctGrowAndIntegralSumDto();
        sumDto.setTaskId(Long.valueOf(rulesTypeEnum.getCode()));
        sumDto.setType(VipGrowDetailTypeEnum.TYPE_1.getValue());
        sumDto.setTaskName(rulesTypeEnum.getName());
        sumDto.setDateTime(nowTime);
        sumDto.setMaxConfig(maxConfig);
        sumDto.setConfigs(sortedList);
        if (StringUtils.isBlank(RulesTypeEnum.mctQueryVipMainTableName(rulesTypeEnum.getCode()))){
            sumDto.setTbName(rulesTypeEnum.getTableName());
        }else{
            //对公查对私表时
            sumDto.setTbName(RulesTypeEnum.mctQueryVipMainTableName(rulesTypeEnum.getCode()));
            sumDto.setMctJoinVipFlag(true);
            sumDto.setMctQueryVipTbName(rulesTypeEnum.getTableName());
        }
        sumDto.setColumnName(rulesTypeEnum.getColumnName());
        sumDto.setDate(nowDate);
        TagProducer tagProducer = null;
        vipGrowDetailDao.sumMctGrowAndIntegral(sumDto,tagProducer);
//        bankPublicPrimitiveDao.updateGrowByTaskIdAndDate(byId.getId().longValue(),nowDate,nowTime);
        return BaseResult.success(true);
    }


}
